# coding=utf-8
import logging
import traceback

from abc import abstractmethod

from app.modules.common.utils import LogProxy

log = logging.getLogger(__name__)


class TaskStatus(object):
    STARTED = 'STARTED'
    DONE = 'DONE'
    FAILED = 'FAILED'
    TIMEOUT = 'TIMEOUT'

class TaskExcecuteError(RuntimeError):
    pass


class TaskParamsError(TaskExcecuteError):
    pass

class Task(object):
    """Executor is executed in a separate process via Process object and is
      managed by the Process Pool Executor
      """

    def __init__(self, name, pipeline=None):
        """Initialize executor to be executed

        name  - task name
        """
        assert isinstance(name, str), 'Parameters validaiton failed'
        # if not args:
        #	args = ("false")  # Create an empty process to schedule it's execution

        # Properties specified by the input parameters -------------------------
        self.name = name
        self.pipeline = pipeline

    def execute(self, params):
        try:
            result = self.__do_execute__(params=params)
            return result
        except Exception, e:
            log.error(traceback.format_exc())
            raise e

    @abstractmethod
    def __do_execute__(self, params={}):
        pass

    def __str__(self):
        return (
            "<{class_name}("
            "id={self.id}, "
            "name=\"{self.name}\""
            "status=\"{self.status}\""
            ")>".format(
                class_name=self.__class__.__name__,
                self=self
            )
        )

    def get_log(self, _log=None):
        if not _log:
            _log = log
        return LogProxy.get_log_proxy(_log, self.pipeline.name)


def task_status(source, status, message=None):
    if message == None:
        return {"source": source.__str__(), "status": status}
    else:
        return {"source": source.__str__(), "status": status, "message": message}

